#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
反检测模块 - 用于伪装浏览器指纹、IP地址等
"""

import random
import time
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class AntiDetection:
    """反检测类"""
    
    def __init__(self):
        self.user_agents = [
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
        ]
        
        self.screen_resolutions = [
            (1920, 1080),
            (1366, 768),
            (1536, 864),
            (1440, 900),
            (1280, 720),
            (1600, 900),
        ]
        
        # 免费代理列表（示例，实际使用时需要有效的代理）
        self.proxy_list = [
            # "http://proxy1:port",
            # "http://proxy2:port",
            # 可以添加免费代理或付费代理
        ]
    
    def get_random_user_agent(self):
        """获取随机User-Agent"""
        return random.choice(self.user_agents)
    
    def get_random_resolution(self):
        """获取随机屏幕分辨率"""
        return random.choice(self.screen_resolutions)
    
    def get_random_proxy(self):
        """获取随机代理"""
        if self.proxy_list:
            return random.choice(self.proxy_list)
        return None
    
    def setup_chrome_options(self, use_proxy=False, headless=False):
        """设置Chrome选项以避免检测"""
        options = Options()

        # 最基本的设置
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-dev-shm-usage')

        # 反检测设置
        options.add_argument('--disable-blink-features=AutomationControlled')
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        options.add_experimental_option('useAutomationExtension', False)

        # 代理设置 - 根据配置决定是否使用代理
        if use_proxy:
            # 尝试从配置文件获取代理列表
            try:
                import config
                config_instance = config.Config()
                proxy_list = config_instance.BROWSER_CONFIG.get('proxy_list', [])

                if proxy_list:
                    # 使用配置文件中的第一个代理
                    proxy = proxy_list[0]
                    options.add_argument(f'--proxy-server={proxy}')
                    print(f"🔄 使用配置代理: {proxy}")
                else:
                    print("⚠️ 代理已启用但未配置代理服务器")
            except Exception as e:
                print(f"⚠️ 读取代理配置失败: {e}")
        else:
            print("🌐 使用直连模式（无代理）")

        # 无头模式
        if headless:
            options.add_argument('--headless')

        # 基本优化（保守设置）
        options.add_argument('--disable-extensions')
        options.add_argument('--disable-plugins')
        options.add_argument('--disable-gpu')
        options.add_argument('--lang=zh-CN')

        return options
    
    def execute_stealth_script(self, driver):
        """执行反检测脚本"""
        stealth_script = """
        // 移除webdriver属性
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined,
        });
        
        // 伪装Chrome对象
        window.chrome = {
            runtime: {},
        };
        
        // 伪装权限查询
        const originalQuery = window.navigator.permissions.query;
        window.navigator.permissions.query = (parameters) => (
            parameters.name === 'notifications' ?
                Promise.resolve({ state: Cypress.env('NOTIFICATION_PERMISSION') || 'granted' }) :
                originalQuery(parameters)
        );
        
        // 伪装插件数量
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5],
        });
        
        // 伪装语言
        Object.defineProperty(navigator, 'languages', {
            get: () => ['zh-CN', 'zh', 'en'],
        });
        """
        
        try:
            driver.execute_script(stealth_script)
        except Exception as e:
            print(f"⚠️ 执行反检测脚本失败: {e}")
    
    def random_delay(self, min_seconds=1, max_seconds=3):
        """随机延迟"""
        delay = random.uniform(min_seconds, max_seconds)
        time.sleep(delay)
        return delay
    
    def human_like_typing(self, element, text, typing_speed=0.1):
        """模拟人类打字"""
        element.clear()
        for char in text:
            element.send_keys(char)
            time.sleep(random.uniform(0.05, typing_speed))
    
    def random_mouse_movement(self, driver):
        """随机鼠标移动"""
        try:
            # 随机滚动
            scroll_amount = random.randint(100, 500)
            driver.execute_script(f"window.scrollBy(0, {scroll_amount});")
            time.sleep(random.uniform(0.5, 1.5))
            
            # 随机移动到页面某个位置
            x = random.randint(100, 800)
            y = random.randint(100, 600)
            driver.execute_script(f"""
                var event = new MouseEvent('mousemove', {{
                    'view': window,
                    'bubbles': true,
                    'cancelable': true,
                    'clientX': {x},
                    'clientY': {y}
                }});
                document.dispatchEvent(event);
            """)
        except Exception as e:
            print(f"⚠️ 鼠标移动模拟失败: {e}")
    
    def clear_browser_data(self, driver):
        """清除浏览器数据（简化版）"""
        try:
            # 只删除cookies，避免localStorage错误
            driver.delete_all_cookies()
        except Exception as e:
            print(f"⚠️ 清除浏览器数据失败: {e}")
